package com.nulldev.util.web.legacyURI;

import java.io.InputStream;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import com.nulldev.util.VariableAPI.ArrayUtils;
import com.nulldev.util.VariableAPI.util.random.GlobalRandom;
import com.nulldev.util.VariableAPI.util.strings.splitters.Splitters;
import com.nulldev.util.VariableAPI.util.strings.splitters.third_party.Splitter;
import com.nulldev.util.data.Variables;
import com.nulldev.util.data.Arrays.maps.FastMaps;
import com.nulldev.util.data.Charsets.CharsetUtil;
import com.nulldev.util.internal.backport.concurrency9.Maps;
import com.nulldev.util.io.IOUtils;
import com.nulldev.util.manage.MarkedForRemoval;
import com.nulldev.util.web.HttpClient.HttpClient;
import com.nulldev.util.web.HttpClient.HttpResponse;
import com.nulldev.util.web.URLUtils.URLUtils;

@MarkedForRemoval(plannedRemovalWhen = "When there are no users for at least ONE nullUtil release.", reason = "Replaced by URLUtils in 3.0.")
public class LegacyURIUtils {
	public static final String USER_AGENT = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";

	@SuppressWarnings("deprecation")
	public static String safeDecode(final String string) {
		Variables.requireNonNull(string, "string");
		try {
			return URLDecoder.decode(string, CharsetUtil.UTF_8.name());
		} catch (Exception e) {
			try {
				return URLDecoder.decode(string);
			} catch (Exception e0) {
				return string;
			}
		}
	}

	@SuppressWarnings("deprecation")
	public static String safeDecode(final String string, final String charset) {
		Variables.requireNonNull(string, "string");
		Variables.requireNonNull(charset, "charset");
		try {
			return URLDecoder.decode(string, charset);
		} catch (Exception e) {
			try {
				return URLDecoder.decode(string);
			} catch (Exception e0) {
				return string;
			}
		}
	}

	@SuppressWarnings("deprecation")
	public static String safeEncode(final String string) {
		Variables.requireNonNull(string, "string");
		try {
			return URLEncoder.encode(string, CharsetUtil.UTF_8.name());
		} catch (Exception e) {
			try {
				return URLEncoder.encode(string);
			} catch (Exception e0) {
				return string;
			}
		}
	}

	@SuppressWarnings("deprecation")
	public static String safeEncode(final String string, final String charset) {
		Variables.requireNonNull(string, "string");
		Variables.requireNonNull(charset, "charset");
		try {
			return URLEncoder.encode(string, charset);
		} catch (Exception e) {
			try {
				return URLEncoder.encode(string);
			} catch (Exception e0) {
				return string;
			}
		}
	}

	private static final Splitter QUERY_STRING_SPLITTER = Splitter.onPattern("\\?|&");
	private static final String BLNK_STR = "";

	@Deprecated
	public static Map<String, String> queryStringToMap(final String query) {
		if (query == null || query.isEmpty())
			return Maps.of();
		final String[] encodedPairs = QUERY_STRING_SPLITTER.splitToArray(query);
		final Map<String, String> hashMap = FastMaps.map(encodedPairs.length);
		for (final String pair : encodedPairs) {
			final String[] splitPair = Splitters.splitString(pair, "=");
			if (splitPair.length == 0)
				continue;
			final String encodedKey = splitPair[0];
			final String encodedValue = ArrayUtils.StringArrayUtils.addFrom(splitPair, 1, '=');
			hashMap.put(URLUtils.safeDecode(encodedKey), URLUtils.safeDecode(encodedValue));
		}
		return hashMap;
	}

	@Deprecated
	public static Map<String, String> queryStringToMap_NoDecode(String query) {
		if (query == null || query.isEmpty())
			return Maps.of();
		String[] encodedPairs = QUERY_STRING_SPLITTER.splitToArray(query); // query.split("\\?|&");
		final Map<String, String> hashMap = FastMaps.map(encodedPairs.length);
		for (String pair : encodedPairs) {
			final String[] splitPair = Splitters.splitString(pair, "="); // pair.split("=");
			if (splitPair.length == 0)
				continue;
			String encodedKey = splitPair[0];
			String encodedValue = splitPair.length == 1 ? BLNK_STR : pair.substring(encodedKey.length() + 1); // ArrayUtils.StringArrayUtils.addFrom(splitPair,
																												// 1, '=');
			hashMap.put(encodedKey, encodedValue);
		}
		return hashMap;
	}

	public static void disableSSLVerification() {
		final TrustManager[] trustAllCerts = new TrustManager[]
			{ new X509TrustManager() {
				public java.security.cert.X509Certificate[] getAcceptedIssuers() {
					return new java.security.cert.X509Certificate[0];
				}

				public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
				}

				public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
				}
			} };
		final HostnameVerifier hv = new HostnameVerifier() {
			public boolean verify(String hostname, SSLSession session) {
				return true;
			}
		};
		try {
			final SSLContext sc = SSLContext.getInstance("SSL");
			sc.init(null, trustAllCerts, GlobalRandom.getGlobalInsecureRandom());
			HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
			HttpsURLConnection.setDefaultHostnameVerifier(hv);
		} catch (Exception e) {
		}
	}

	public static int getResponseCode(final URL url) {
		try {
			final HttpResponse<InputStream> r = HttpClient.getStream().url(Variables.requireNonNullObject(url, "url")).create();
			final int resp = r.status();
			IOUtils.closeQuietly(r);
			return resp;
		} catch (Exception e) {
			return 404;
		}
	}
}
